package com.lac.component.controller;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import com.lac.component.dao.GoodsSpuChannel;
import com.lac.component.dao.GoodsSpuChannelMapper;
import com.lac.component.utils.OSSUrlUploader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Type;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author xiaokuixiao
 * date2025/7/31 14:29
 */
@RestController
@Slf4j
public class GoodsSpuChannelController {
    @Autowired
    private GoodsSpuChannelMapper goodsSpuChannelMapper;

    @GetMapping("/draftJson")
    public String   draftJson() {
        StringBuffer combinedSql = new StringBuffer();
        StringBuffer deleteCombinedSql = new StringBuffer();
        List<GoodsSpuChannel> goodsSpuChannels = goodsSpuChannelMapper.getGoodsSpuChannel();
//        goodsSpuChannels = goodsSpuChannels.stream().limit(1).collect(Collectors.toList());
        List<String> idList = new ArrayList<>();
        List<String> serverNamesMutable = new ArrayList<>(Arrays.asList("wm-dev-b1", "wm-prod-b1", "em-dev-b1", "em-prod-b1"));
        // 遍历所有需要处理的商品，或者只处理第一个/特定id的
        // 这里只是示例，通常你会有一个循环

        for (int i = 0; i < goodsSpuChannels.size(); i++) {
            GoodsSpuChannel goodsSpuChannel = goodsSpuChannels.get(i);
            String OldDraftJson = goodsSpuChannel.getDraftJson();
            String newDraftJson = updateImages(OldDraftJson, serverNamesMutable);
            String OldReleaseJson = goodsSpuChannel.getReleaseJson();
            String newReleaesJson = updateImages(OldReleaseJson, serverNamesMutable);
            String url = "https://wm-prod-b1.oss-cn-beijing.aliyuncs.com/common/video";
            String imageUrl = "https://wm-prod-b1.oss-cn-beijing.aliyuncs.com/common/material";
            // 比较新旧JSON字符串，避免不必要的更新
            if ((!newDraftJson.equals(OldDraftJson) || newDraftJson.contains(url)||newDraftJson.contains(imageUrl)) && (!newReleaesJson.equals(OldReleaseJson) || newReleaesJson.contains(url)||newReleaesJson.contains(imageUrl))) {
                String escapedDraftJson= newDraftJson.replace("'", "''"); // 简单的单引号转义
                String replaceReleaesJson = newReleaesJson.replace("'", "''");
                String goodsSpuId = goodsSpuChannel.getId().replace("'", "''"); // 简单的单引号转义

                String updateSql = String.format(
                        "UPDATE `oms_mall`.`goods_spu_channel` SET `%s` = '%s' , `%s` = '%s' WHERE  `id` = '%s';",
                        "draft_json", escapedDraftJson, "release_json", replaceReleaesJson,
                        goodsSpuId
                );
                // 构建SQL更新语句
//                String updateSql = buildUpdateSql(goodsSpuChannel.getId(), newDraftJson, "draft_json");

                combinedSql.append(updateSql).append("\n");

                String deleteSql = buildDeleteSql(goodsSpuChannel.getId());

                deleteCombinedSql.append(deleteSql).append("\n");
            }else if((!newDraftJson.equals(OldDraftJson) || newDraftJson.contains(url)||newDraftJson.contains(imageUrl))&& newReleaesJson.equals(OldReleaseJson)) {
                String updateSql = buildUpdateSql(goodsSpuChannel.getId(), newDraftJson, "draft_json");

                combinedSql.append(updateSql).append("\n");

                String deleteSql = buildDeleteSql(goodsSpuChannel.getId());

                deleteCombinedSql.append(deleteSql).append("\n");
            }else if(newDraftJson.equals(OldDraftJson) && (!newReleaesJson.equals(OldReleaseJson) || newReleaesJson.contains(url)||newReleaesJson.contains(imageUrl))) {
                String updateSql = buildUpdateSql(goodsSpuChannel.getId(), newReleaesJson, "release_json");

                combinedSql.append(updateSql).append("\n");

                String deleteSql = buildDeleteSql(goodsSpuChannel.getId());

                deleteCombinedSql.append(deleteSql).append("\n");
            } else {
                idList.add(goodsSpuChannel.getId());
                System.out.println("GoodsSpu ID: " + goodsSpuChannel.getId() + " 的图片URL没有变化，无需更新。");
            }
            log.info("条数============================================={}", i+1);
        }
        log.info("combinedSql:{}", combinedSql);
        if (idList.size() > 0) {
            String goodsSpuId = String.join(",", idList);
            String selectSql = "SELECT * FROM `oms_mall`.`goods_spu_channel` WHERE `id` IN (" + goodsSpuId + ");";
            String string = combinedSql.append(deleteCombinedSql).append(selectSql).toString();
            log.info("selectSql:{}", string);
            return string;
        } else {
            String string = combinedSql.append(deleteCombinedSql).toString();
            log.info("selectSql:{}",string);
            return string;
        }
    }

    public String updateImages(String oldDraftJson, List<String> serverNamesMutable) {
        try {
            if (oldDraftJson == null || oldDraftJson.isEmpty()) {
                // Handle the case where draft JSON is missing
                System.out.println("Draft JSON is null or empty. Skipping image update.");
                return oldDraftJson; // Or throw an exception, depending on your needs
            }
            Gson gson = new GsonBuilder().disableHtmlEscaping() // 禁用 HTML 字符的转义
                    .create();
            JsonObject json = gson.fromJson(oldDraftJson, JsonObject.class);
            if (json == null) {
                // Handle the case where JSON parsing fails
                System.err.println("Failed to parse draft JSON.");
                return oldDraftJson;
            }
            JsonElement picUrlsElement = json.get("picUrls");
            if (picUrlsElement != null && picUrlsElement.isJsonArray()) {
                String oldPicUrlsJson = gson.toJson(picUrlsElement);
                String newPicUrlsJson = checkAndReuploadPicUrls(oldPicUrlsJson, serverNamesMutable);

                if (newPicUrlsJson != null && !newPicUrlsJson.equals(oldPicUrlsJson)) {
                    JsonArray newPicUrlsArray = gson.fromJson(newPicUrlsJson, JsonArray.class); // Parse back for setting
                    json.add("picUrls", newPicUrlsArray); // or json.set("picUrls",newPicUrlsJson)
                }
            } else {
                System.out.println("picUrls is not an array or is missing. Skipping picUrls update.");
            }
            JsonElement descriptionElement = json.get("description");
            if (descriptionElement != null && descriptionElement.isJsonPrimitive()) {  // Check if description is present and is a string value
                processDescriptionField(gson, json, serverNamesMutable);
            } else {
                System.out.println("description is not a string or is missing. Skipping description update.");
            }
            return gson.toJson(json);
        } catch (Exception e) {
            System.err.println("An error occurred during image update: " + e.getMessage());
            e.printStackTrace(); // Log the full exception details for debugging
            return oldDraftJson;
        }
    }





    public static String checkAndReuploadPicUrls(String picUrlsJson,  List<String> serverNames) {
        Gson gson = new Gson();
        Type listType = new TypeToken<List<String>>() {
        }.getType();
        List<String> urlList = null;
        try {
            urlList = gson.fromJson(picUrlsJson, listType);
        } catch (Exception e) {
            log.error(" picUrls JSON失败: {}, JSON: {}", e.getMessage(), picUrlsJson);
        }
        // 存储新生成的OSS URL
        List<String> ossUrls = new ArrayList<>();
        boolean hasAnyUrlUploaded = false; // 标记是否有任何一个URL成功上传

        if (urlList != null && !urlList.isEmpty()) { // 确保urlList不为null且不为空
            for (String picUrl : urlList) {
                String ossUrl = null;
                boolean isUploaded = false;
                for (String serverName : serverNames) {
                    if (picUrl.contains(serverName)) {
                        isUploaded = true;
                    }
                }
                if (StringUtils.isNotBlank(picUrl) && !isUploaded) {
                    try {
                        ossUrl = OSSUrlUploader.uploadFromUrlWithSnowflakeName(picUrl, "common/material");
                        if (StringUtils.isNotBlank(ossUrl)) {
                            ossUrls.add(ossUrl);
                            hasAnyUrlUploaded = true;
                        } else {
                            // 如果上传返回空，保留原URL以防止数据丢失，或者记录错误
                            log.warn("图片 {} 上传到OSS返回空URL，将保留原URL。", picUrl);
                            ossUrls.add(picUrl); // 保持原有的URL
                        }
                    } catch (Exception e) {
                        log.error("上传图片异常{},原始URL:{},错误信息:{}", e.getClass().getSimpleName(), picUrl, e.getMessage());
                        // 如果上传失败，保留原始URL，避免数据丢失
                        ossUrls.add(picUrl);
                    }
                } else {
                    // 如果原始URL是空白的，也加入到新列表中，保持数组结构
                    ossUrls.add(picUrl);
                }
            }
        }
        // 只有当有图片成功上传或列表结构发生变化时才更新
        // 确保即使所有上传都失败，但是原始picUrls存在，我们也会生成一个新的JSON字符串 (可能包含原始URL)
        String newPicUrlsJson = gson.toJson(ossUrls);
        return newPicUrlsJson;
    }

    /**
     * 检查并重新上传图片到OSS
     * @param htmlContent 包含图片URL的HTML内容
     * @param serverNames 需要重新上传的服务器名称列表
     * @return 更新后的HTML内容
     */
    public static String checkAndReuploadImages(String htmlContent, List<String> serverNames) {
        if (StringUtils.isBlank(htmlContent)) {
            return htmlContent;
        }

        // 增强版正则表达式：匹配img/video标签的src和a标签的href
        String regex = "<(a|img|video)(\\s+[^>]*?)?\\s+(href|src)\\s*=\\s*([\"']?)([^\"'\\s>]+)\\4(\\s*/?>|\\s+[^>]*?>)";
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
        Matcher matcher = pattern.matcher(htmlContent);
        StringBuffer result = new StringBuffer();

        // 存储已处理的 URL 避免重复上传
        Map<String, String> processedUrls = new HashMap<>();

        while (matcher.find()) {
            String fullTag = matcher.group(0);
            String tagType = matcher.group(1).toLowerCase(); // a, img 或 video
            String attrType = matcher.group(3).toLowerCase(); // href 或 src
            String quoteChar = matcher.group(4); // 使用的引号（"、' 或空）
            String resourceUrl = matcher.group(5); // 资源URL

            // 修复可能被截断的URL（常见于无引号属性）
            if (resourceUrl.endsWith("/>") || resourceUrl.endsWith(">")) {
                resourceUrl = resourceUrl.replaceAll("[/>]+$", "");
            }

            log.info("处理 {} 标签的 {} 属性: {}, URL: {}", tagType, attrType, fullTag, resourceUrl);

            // 检查是否需要重新上传
            boolean shouldSkip = false;
            for (String serverName : serverNames) {
                if (resourceUrl.contains(serverName)) {
                    log.info("URL 包含 serverName {}, 跳过重新上传", serverName);
                    shouldSkip = true;
                    break;
                }
            }

            String newResourceUrl = resourceUrl;

            // 检查是否已处理过相同 URL
            if (processedUrls.containsKey(resourceUrl)) {
                newResourceUrl = processedUrls.get(resourceUrl);
                log.info("使用缓存 URL: {} -> {}", resourceUrl, newResourceUrl);
            }
            // 需要处理且是有效的 HTTP URL
            else if (!shouldSkip && StringUtils.isNotBlank(resourceUrl)
                    && (resourceUrl.startsWith("http") || resourceUrl.startsWith("https"))) {
                try {
                    // 根据标签和属性类型选择上传目录
                    String uploadPath;
                    if ("a".equals(tagType)) {
                        // a标签的href按图片处理
                        uploadPath = "common/material";
                    } else {
                        // img/video标签根据标签类型处理
                        uploadPath = "img".equals(tagType)
                                ? "common/material"
                                : "common/video";
                    }

                    newResourceUrl = OSSUrlUploader.uploadFromUrlWithSnowflakeName(
                            resourceUrl, uploadPath
                    );

                    // 缓存处理结果
                    processedUrls.put(resourceUrl, newResourceUrl);
                    log.info("上传成功: {} => {}", resourceUrl, newResourceUrl);
                } catch (Exception e) {
                    log.error("重新上传 {} 的 {} 属性失败: {}", tagType, attrType, resourceUrl, e);
                    // 失败时保留原 URL
                    newResourceUrl = resourceUrl;
                }
            } else {
                log.info("跳过处理: {} (原因: {})", resourceUrl,
                        shouldSkip ? "匹配到serverName" : "非HTTP URL");
            }

            // 安全替换 URL - 保持原始引号格式
            String newTag = fullTag.replace(resourceUrl, newResourceUrl);
            matcher.appendReplacement(result, Matcher.quoteReplacement(newTag));
        }
        matcher.appendTail(result);

        return result.toString();
    }
    private void processDescriptionField(Gson gson, JsonObject json, List<String> serverNames) {
        JsonElement descElement = json.get("description");
        if (descElement == null || !descElement.isJsonPrimitive()) return;

        String oldDesc = descElement.getAsString();
        if (StringUtils.isBlank(oldDesc)) return;

        // 处理图片并获取新HTML
        String newDesc = checkAndReuploadImages(oldDesc, serverNames);

        // 核心修复：双重转义
        if (newDesc != null && !newDesc.equals(oldDesc)) {
            // 步骤1：将HTML转换为JSON安全字符串
            String escapedHtml = gson.toJson(newDesc);

            // 步骤2：移除Gson添加的多余引号
            if (escapedHtml.startsWith("\"") && escapedHtml.endsWith("\"")) {
                escapedHtml = escapedHtml.substring(1, escapedHtml.length() - 1);
            }

            // 步骤3：更新JSON对象
            json.addProperty("description", escapedHtml);
        }
    }

    /**
     * 构建SQL UPDATE语句的辅助方法
     * @param goodsSpuId 商品ID
     * @param newPicUrlsJson 新的图片URL JSON字符串
     * @return SQL UPDATE语句
     */
    private String buildUpdateSql(String  goodsSpuId, String newPicUrlsJson ,String featureName) {
        // 注意：实际生产环境中，请使用PreparedStatement防止SQL注入！
        // 这里的拼接仅用于演示生成的SQL字符串。

        // 为了SQL安全，需要对newPicUrlsJson进行适当的转义，特别是单引号
        // 通常数据库驱动或ORM框架会自动处理
        String escapedNewPicUrlsJson = newPicUrlsJson.replace("'", "''"); // 简单的单引号转义
        goodsSpuId = goodsSpuId.replace("'", "''"); // 简单的单引号转义

        return String.format(
                "UPDATE `oms_mall`.`goods_spu_channel` SET `%s` = '%s' WHERE `id` = '%s';",
                featureName, escapedNewPicUrlsJson,
                goodsSpuId
        );
    }

    /**
     * 构建SQL DELETE语句的辅助方法
     * @param goodsSpuId 商品ID
     * @return SQL DELETE语句
     */
    private String buildDeleteSql(String  goodsSpuId) {
        return String.format("DELETE FROM `oms_mall`.`goods_spu_channel` WHERE `id` = %s;","'"+goodsSpuId+"'");
    }


}


